# -*- coding: utf-8 -*-
"""
# @created on : 9月 2021/9/15 20:21
# @author     : kevin
# @file       : compare.py
# @software   : PyCharm
# @project    : auto_interface_test


@license: (C) Copyright 2019-2025, Corporation Limited.
@desc:
JsonPath语法要点：

$ 表示文档的根元素
@ 表示文档的当前元素
.node_name 或 ['node_name'] 匹配下级节点
[index] 检索数组中的元素
[start:end:step] 支持数组切片语法
* 作为通配符，匹配所有成员
.. 子递归通配符，匹配成员的所有子元素
(<expr>) 使用表达式
?(<boolean expr>)进行数据筛选

"""
import ast
import jsonpath
from common.logger import Logger
from utils.operation_excel import OperationExcel
from utils.operation_response import OperationResponse


class Compare:
    def __init__(self):
        self.log = Logger()
        self.op = OperationExcel(sheet_name='data')
        self.res = OperationResponse()

    def is_contains(self, str1, str2):
        flag = None
        if str1 in str2:
            flag = True
        else:
            flag = False
        return flag

    def write_result_to_excel(self, row, value):
        # 将实际结果写入用例
        self.op.set_cell_value(row, 13, value, 'result')

    def equality(self, value, check):
        """
        判断value类型后对value与check值进行比较相
        :param value: 预期
        :param check:
        :return:
        """
        flag = None
        if isinstance(value, str):
            if check == value:
                flag = True
            else:
                flag = False
        elif isinstance(value, float):
            if value - float(check) == 0:
                flag = True
            else:
                flag = False
        elif isinstance(value, int):
            if value - int(check) == 0:
                flag = True
            else:
                flag = False
        return flag

    def sub_string(self, value, check):
        flg = None
        if str(value).find(check) >= 0:
            flg = True
        else:
            flg = False
        return flg

    def write_pass_result(self, row, i, value, check, assert_type):
        # 将成功结果写入用例
        self.op.set_cell_value(row, 14, 'PASS', 'PASS')
        self.log.logger('info', f"当前为第{i + 1}个检查点，  实际结果：{value},   预期结果: {check},  断言方法：\"{assert_type}\",  验证通过！")
        print(f"当前为第{i + 1}个检查点，  实际结果：{value},   预期结果: {check},  断言方法：\"{assert_type}\",  验证通过！")

    def write_fall_result(self, row, i, value, check, assert_type):
        # 将失败结果写入用例
        self.op.set_cell_value(row, 14, 'FALL', 'FALL')
        self.log.logger('info', f"当前为第{i + 1}个检查点，  实际结果：{value},   预期结果: {check},  断言方法：\"{assert_type}\",  验证失败！")
        print(f"当前为第{i + 1}个检查点，  实际结果：{value},   预期结果: {check},  断言方法：\"{assert_type}\" ,  验证失败！")

    def check(self, row, type, response, check_point):
        flg = None
        if type == 'status':
            flg = self.check_status(row, str(response.status_code), check_point)
        # elif type == 'request':
        #     flg = self.check_request(row, response.headers, check_point)
        elif type == 'url':
            flg = self.check_url(row, ast.literal_eval(response.url), check_point)
        elif type == 'header':
            flg = self.check_header(row, response, check_point)
        elif type == 'response':
            flg = flg = self.check_response(row, response, check_point)
        elif type == 'json':
            flg = self.check_json(row, response.text, check_point)
        else:
            flg = self.log('error', '要断言的类型错误！！！')
            return False
        return flg

    def check_status(self, row, response, check_point):
        flg = None
        value = check_point.split(' ')[2]
        assert_type = check_point.split(' ')[1]
        self.write_result_to_excel(row, response)
        if assert_type == '=' or assert_type == 'equals':
            if self.equality(value, response):
                flg = True
                self.write_pass_result(row, 0, response, value, assert_type)
            else:
                self.write_fall_result(row, 0, response, value, assert_type)
                flg = False
        elif assert_type == '!=' or assert_type == 'not':
            if self.equality(value, response):
                self.write_fall_result(row, 0, response, value, assert_type)
                flg = False
            else:
                self.write_pass_result(row, 0, response, value, assert_type)
                flg = True
        return flg

    # def check_request(self, row, response, check_point):
    #     flg = None
    #     c = check_point.split(';')
    #     for i in range(len(c)):
    #         check_point_dict = {}
    #         check_point_dict[c[i].split(' ')[0]] = c[i].split(' ')[2]
    #         value = self.res.get_value_from_xml_by_key(response.request, c[i].split(' ')[0])
    #         self.write_result_to_excel(row, value)
    #         check = check_point_dict[c[i].split(" ")[0]]
    #         flg = self.equality(value, check)
    #         if c[i].aplit(' ')[1] == '=' or c[i].aplit(' ')[1] == 'equals':
    #             if flg:
    #                 self.write_pass_result(row, 1, value, check)
    #             else:
    #                 self.write_fall_result(row, 1, value, check)
    #         elif c[i].aplit(' ')[1] == '!=' or c[i].aplit(' ')[1] == 'not':
    #             if flg:
    #                 self.write_fall_result(row, 1, value, check)
    #             else:
    #                 self.write_pass_result(row, 1, value, check)
    #         elif c[i].aplit(' ')[1] == 'subString':
    #             flg = self.sub_string(value, check)
    #             if flg:
    #                 self.write_pass_result(row, 1, value, check)
    #             else:
    #                 self.write_fall_result(row, 1, value, check)
    #         else:
    #             self.log.logger('info', f'断言方法错误，请检查！')
    #     return flg

    def check_url(self, row, response, check_point):
        flg = None
        value = response.url
        self.write_result_to_excel(row, value)
        check = check_point.split[' '][2]
        assert_type = check_point.split(' ')[1]
        flg = self.equality(value, check)
        if assert_type == '=' or assert_type == 'equals':
            if flg:
                self.write_pass_result(row, 0, value, check, assert_type)
            else:
                self.write_fall_result(row, 0, value, check, assert_type)
        elif assert_type == '!=' or assert_type == 'not':
            if flg:
                self.write_fall_result(row, 0, value, check, assert_type)
            else:
                self.write_pass_result(row, 0, value, check, assert_type)
        else:
            self.log.logger('error', f'断言方法错误，请检查！')
        return flg

    def check_header(self, row, response, check_point):
        flg = None
        check = check_point.split(' ')[2]
        value = response.headers[check_point.split(' ')[0]]
        self.write_result_to_excel(row, value)
        assert_type = check_point.split(' ')[1]
        if assert_type == '=' or assert_type == 'equals':
            flg = self.equality(value, check)
            if flg:
                self.write_pass_result(row, 0, value, check, assert_type)
            else:
                self.write_fall_result(row, 0, value, check, assert_type)
        elif assert_type == '!=' or assert_type == 'not':
            flg = self.equality(value, check)
            if flg:
                self.write_fall_result(row, 0, value, check, assert_type)
            else:
                self.write_pass_result(row, 0, value, check, assert_type)
        elif assert_type == 'subString':
            flg = self.sub_string(value, check)
            if flg:
                self.write_pass_result(row, 0, value, check, assert_type)
            else:
                self.write_fall_result(row, 0, value, check, assert_type)
        else:
            self.log.logger('info', f'断言方法错误，请检查！')
        return flg

    def check_response(self, row, response, check_point):
        flg = None
        c = check_point.split(';')

        for i in range(len(c)):
            assert_type = c[i].split(' ')[1]
            check_point_dict = {}
            check_point_dict[c[i].split(' ')[0]] = c[i].split(' ')[2]
            value = self.res.get_value_from_xml_by_key(response, c[i].split(' ')[0])
            self.write_result_to_excel(row, value)
            check = check_point_dict[c[i].split(" ")[0]]
            flg = self.equality(value, check)
            if assert_type == '=' or assert_type == 'equals':
                if flg:
                    self.write_pass_result(row, 0, value, check, assert_type)
                else:
                    self.write_fall_result(row, 0, value, check, assert_type)
            elif assert_type == '!=' or assert_type == 'not':
                if flg:
                    self.write_fall_result(row, 0, value, check, assert_type)
                else:
                    self.write_pass_result(row, 0, value, check, assert_type)
            elif assert_type == 'subString':
                flg = self.sub_string(value, check)
                if flg:
                    self.write_pass_result(row, 0, value, check, assert_type)
                else:
                    self.write_fall_result(row, 0, value, check, assert_type)
            else:
                self.log.logger('info', f'断言方法错误，请检查！')
        return flg

    def check_json(self, row, response, check_point):
        """
        通过获取预期结果与返回内容中获取到的检查点的值做比较，结果相同则通过，结果不同则失败
        :param response: 预期结果
        :param check_point: json检查点函数
        :return:
        """
        # 通过;拆分检查点
        c = check_point.split(";")
        flag = None
        # 循环对检查点取值并调用比较函数进行比较
        for i in range(0, len(c)):
            check_point_dict = {}
            assert_type = c[i].split(" ")[1]
            check_point_dict[c[i].split(" ")[0]] = c[i].split(" ")[2]
            # 由于传入的response为str类型，在进行结果确认前需要先转换一下格式
            # value = jsonpath.jsonpath(ast.literal_eval(response), c[i].split(" ")[0])[0]
            value = self.res.get_value_from_json_by_key(response, c[i].split(" ")[0])
            # 将实际结果写入用例
            self.write_result_to_excel(row, value)
            check = check_point_dict[c[i].split(" ")[0]]
            # print(f"检查点{i + 1}:实际结果：{value}, 预期结果:{check}")
            if assert_type == '=' or assert_type == 'equals':
                flag = self.equality(value, check)
                if flag:
                    # 将成功结果写入用例
                    self.write_pass_result(row, i, value, check, assert_type)
                else:
                    # 将失败结果写入用例
                    self.write_fall_result(row, i, value, check, assert_type)
            elif assert_type == '!=' or assert_type == 'not':
                flag = self.equality(value, check)
                if flag:
                    # 将失败结果写入用例
                    self.write_fall_result(row, i, value, check, assert_type)
                else:
                    # 将成功结果写入用例
                    self.write_pass_result(row, i, value, check, assert_type)
            elif assert_type == 'subString':
                flag = self.sub_string(value, check)
                if flag:
                    # 将成功结果写入用例
                    self.write_pass_result(row, i, value, check, assert_type)
                else:
                    # 将失败结果写入用例
                    self.write_fall_result(row, i, value, check, assert_type)
            else:
                self.log.logger('info', f'断言方法错误，请检查！')
        return flag
